import Axios, {
  type AxiosInstance,
  type AxiosRequestConfig,
  type CustomParamsSerializer
} from "axios";
import type {
  PureHttpError,
  RequestMethods,
  PureHttpResponse,
  PureHttpRequestConfig
} from "./types.d";
import { stringify } from "qs";
import NProgress from "../progress";
import { getToken, formatToken } from "@/utils/auth";
// import { useUserStoreHook } from "@/store/modules/user";

// 相关配置请参考：www.axios-js.com/zh-cn/docs/#axios-request-config-1
const defaultConfig: AxiosRequestConfig = {
  // 请求超时时间
  timeout: 10000,
  headers: {
    Accept: "application/json, text/plain, */*",
    "Content-Type": "application/json",
    "X-Requested-With": "XMLHttpRequest"
  },
  // 数组格式参数序列化（https://github.com/axios/axios/issues/5142）
  paramsSerializer: {
    serialize: stringify as unknown as CustomParamsSerializer
  }
};

class PureHttp {
  constructor() {
    this.httpInterceptorsRequest();
    this.httpInterceptorsResponse();
  }

  /** `token`过期后，暂存待执行的请求 */
  private static requests = [];

  /** 防止重复刷新`token` */
  private static isRefreshing = false;

  /** 初始化配置对象 */
  private static initConfig: PureHttpRequestConfig = {};

  /** 保存当前`Axios`实例对象 */
  private static axiosInstance: AxiosInstance = Axios.create(defaultConfig);

  /** 重连原始请求 */
  private static retryOriginalRequest(config: PureHttpRequestConfig) {
    return new Promise(resolve => {
      PureHttp.requests.push((token: string) => {
        config.headers["Authorization"] = formatToken(token);
        resolve(config);
      });
    });
  }

  /** 请求拦截 */
  private httpInterceptorsRequest(): void {
    PureHttp.axiosInstance.interceptors.request.use(
      async (config: any): Promise<any> => {
        // 开启进度条动画
        NProgress.start();

        // 处理自定义请求回调
        if (typeof config.beforeRequestCallback === "function") {
          config.beforeRequestCallback(config);
          return config;
        }
        if (PureHttp.initConfig.beforeRequestCallback) {
          PureHttp.initConfig.beforeRequestCallback(config);
          return config;
        }

        // 请求白名单（不需要Token的接口）
        const whiteList = ["/refresh-token", "/login"];
        const isWhiteUrl = whiteList.some(url => config.url.endsWith(url));

        // 获取Token数据
        const tokenData = getToken();

        // 非白名单接口且存在Token时，添加到请求头
        if (!isWhiteUrl && tokenData && tokenData.token) {
          // 使用标准Authorization字段 + Bearer格式（推荐做法）
          config.headers["Authorization"] = formatToken(tokenData.token);
        }

        // Token过期处理
        if (tokenData) {
          const now = new Date().getTime();
          const isExpired = parseInt(tokenData.expireTime) - now <= 0;

          // Token过期且未在刷新中
          if (isExpired && !PureHttp.isRefreshing) {
            PureHttp.isRefreshing = true;

            // 临时模拟Token刷新（开发环境测试用，正式环境需移除）
            config.headers["Authorization"] = formatToken(tokenData.token);
            console.log("token是", config.headers["Authorization"]);
            PureHttp.requests.forEach(cb => cb(tokenData.token));
            PureHttp.requests = [];
          }
        }

        return config;
      },
      (error: any) => {
        NProgress.done(); // 错误时关闭进度条
        return Promise.reject(error);
      }
    );
  }

  /** 响应拦截 */
  /** 响应拦截 */
  private httpInterceptorsResponse(): void {
    const instance = PureHttp.axiosInstance;
    instance.interceptors.response.use(
      (response: PureHttpResponse) => {
        const $config = response.config;
        // 关闭进度条动画
        NProgress.done();

        // 优先执行自定义响应回调
        if (typeof $config.beforeResponseCallback === "function") {
          $config.beforeResponseCallback(response);
        } else if (PureHttp.initConfig.beforeResponseCallback) {
          PureHttp.initConfig.beforeResponseCallback(response);
        }

        // 检查后端返回的 code 字段
        const resData = response.data;
        if (resData && typeof resData.code !== "undefined") {
          if (resData.code === 1) {
            // code 为 1，返回成功数据
            return resData; // 返回实际数据部分
          } else {
            return Promise.reject(resData);
          }
        }

        // 如果没有 code 字段，直接返回原始响应数据
        return resData;
      },
      (error: PureHttpError) => {
        const $error = error;
        $error.isCancelRequest = Axios.isCancel($error);
        // 关闭进度条动画
        NProgress.done();

        // 处理网络错误
        if (!$error.response) {
          $error.message = "网络连接失败，请检查网络设置";
        }

        return Promise.reject($error);
      }
    );
  }

  /** 通用请求工具函数 */
  public request<T>(
    method: RequestMethods,
    url: string,
    param?: AxiosRequestConfig,
    axiosConfig?: PureHttpRequestConfig
  ): Promise<T> {
    const config = {
      method,
      url,
      ...param,
      ...axiosConfig
    } as PureHttpRequestConfig;
    // 单独处理自定义请求/响应回调
    return new Promise((resolve, reject) => {
      PureHttp.axiosInstance
        .request(config)
        .then((response: undefined) => {
          resolve(response);
        })
        .catch(error => {
          reject(error);
        });
    });
  }

  /** 单独抽离的`post`工具函数 */
  public post<T, P>(
    url: string,
    params?: AxiosRequestConfig<P>,
    config?: PureHttpRequestConfig
  ): Promise<T> {
    return this.request<T>("post", url, params, config);
  }

  /** 单独抽离的`get`工具函数 */
  public get<T, P>(
    url: string,
    params?: AxiosRequestConfig<P>,
    config?: PureHttpRequestConfig
  ): Promise<T> {
    return this.request<T>("get", url, params, config);
  }
}

export const http = new PureHttp();
